import * as Cesium from 'cesium';
import * as turf from '@turf/turf';
import GisTools from '../GisTools';
class MounseEvent {
  handler: any;
  constructor() {
    this.handler = null;
  }
  add(viewer: any, eventType: String, unPickLayers: Array<string>, callback: any) {
    switch (eventType) {
      case 'LEFT_CLICK':
        this.addLeftClickEvent(viewer, unPickLayers, callback);
        break;
      case 'RIGHT_CLICK':
        this.addRightClickEvent(viewer, unPickLayers, callback);
        break;
      case 'MOUSE_MOVE':
        this.addMouseMoveEvent(viewer, callback);
        break;
      default:
        break;
    }
  }
  remove(viewer: any, eventType: String) {
    switch (eventType) {
      case 'LEFT_CLICK':
        this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
        break;
      case 'RIGHT_CLICK':
        this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        break;
      case 'MOUSE_MOVE':
        this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
        break;
      default:
        break;
    }
  }
  addLeftClickEvent(viewer: Cesium.Viewer, unPickLayers: Array<string>, callback: any) {
    let callbackObj = {
      position: {},
      car3Position: <any>{},
      entity: {},
      cesium3DtilesFeature: {},
      staggeredEntities: <any>[],
    };
    if (!this.handler) {
      this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    }
    let _this = this;
    this.handler.setInputAction(function (event: Cesium.ScreenSpaceEventHandler.PositionedEvent) {
      callbackObj = {
        position: {},
        car3Position: <any>{},
        entity: {},
        cesium3DtilesFeature: {},
        staggeredEntities: <any>[],
      };
      callbackObj.position = event.position;
      const pick = viewer.scene.pick(event.position);
      callbackObj.car3Position = _this.getCartesian3FromPick(viewer, event.position);
      if (pick instanceof Cesium.Cesium3DTileFeature) {
        callbackObj.cesium3DtilesFeature = pick;
      }
      if (pick && pick.id) {
        let entity: Cesium.Entity = pick.id;
        callbackObj.entity = entity;
      }
      viewer.dataSources['_dataSources'].forEach((dataSource: any) => {
        if (unPickLayers.indexOf(dataSource._name) === -1) {
          dataSource.entities._entities._array.forEach((entity: any) => {
            if (entity._point) {
              const position = entity._position._value;
              if (Cesium.Cartesian3.equals(position, callbackObj.car3Position)) {
                callbackObj.staggeredEntities.push(entity);
              }
            }
            if (entity._polygon) {
              let { latitude, longitude } = GisTools.Cartesian3ToLngLat(callbackObj.car3Position);
              var pt = turf.point([longitude, latitude]);
              const polPositions = entity._polygon._hierarchy._value.positions;
              let tmpArr = [];
              for (let i = 0; i < polPositions.length; i++) {
                let res: any = GisTools.Cartesian3ToLngLat(polPositions[i]);
                tmpArr.push([res.longitude, res.latitude]);
              }
              tmpArr.push(tmpArr[tmpArr.length - 1]);
              var poly = turf.polygon([tmpArr]);
              if (turf.booleanPointInPolygon(pt, poly)) {
                callbackObj.staggeredEntities.push(entity);
              }
            }
            if (entity._polyline) {
              let { latitude, longitude } = GisTools.Cartesian3ToLngLat(callbackObj.car3Position);
              var pt = turf.point([longitude, latitude]);
              const polPositions = entity._polyline._positions._value;
              let tmpArr = [];
              for (let i = 0; i < polPositions.length; i++) {
                let res: any = GisTools.Cartesian3ToLngLat(polPositions[i]);
                tmpArr.push([res.longitude, res.latitude]);
              }
              var line = turf.lineString(tmpArr);
              if (turf.booleanPointOnLine(pt, line)) {
                callbackObj.staggeredEntities.push(entity);
              }
            }
          });
        }
      });
      if (callback) {
        callback(callbackObj);
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  }
  addMouseMoveEvent(viewer: Cesium.Viewer, callback: any) {
    let callbackObj = {
      position: {},
    };
    if (!this.handler) {
      this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    }
    this.handler.setInputAction(function (event: Cesium.ScreenSpaceEventHandler.MotionEvent) {
      callbackObj = {
        position: {},
      };
      callbackObj.position = event;
      if (callback) {
        callback(callbackObj);
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  }
  addRightClickEvent(viewer: Cesium.Viewer, unPickLayers: Array<string>, callback: any) {
    let callbackObj = {
      position: {},
      car3Position: <any>{},
      entity: {},
      cesium3DtilesFeature: {},
      staggeredEntities: <any>[],
    };
    if (!this.handler) {
      this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    }
    let _this = this;
    this.handler.setInputAction(function (event: Cesium.ScreenSpaceEventHandler.PositionedEvent) {
      callbackObj = {
        position: {},
        car3Position: <any>{},
        entity: {},
        cesium3DtilesFeature: {},
        staggeredEntities: <any>[],
      };
      callbackObj.position = event.position;
      const pick = viewer.scene.pick(event.position);
      console.log(pick);
      callbackObj.car3Position = _this.getCartesian3FromPick(viewer, event.position);
      if (pick instanceof Cesium.Cesium3DTileFeature) {
        callbackObj.cesium3DtilesFeature = pick;
      }
      if (pick && pick.id) {
        let entity: Cesium.Entity = pick.id;
        callbackObj.entity = entity;
      }
      viewer.dataSources['_dataSources'].forEach((dataSource: any) => {
        if (unPickLayers.indexOf(dataSource._name) === -1) {
          dataSource.entities._entities._array.forEach((entity: any) => {
            if (entity._point) {
              const position = entity._position._value;
              if (Cesium.Cartesian3.equals(position, callbackObj.car3Position)) {
                callbackObj.staggeredEntities.push(entity);
              }
            }
            if (entity._polygon) {
              let { latitude, longitude } = GisTools.Cartesian3ToLngLat(callbackObj.car3Position);
              var pt = turf.point([longitude, latitude]);
              const polPositions = entity._polygon._hierarchy._value.positions;
              let tmpArr = [];
              for (let i = 0; i < polPositions.length; i++) {
                let res: any = GisTools.Cartesian3ToLngLat(polPositions[i]);
                tmpArr.push([res.longitude, res.latitude]);
              }
              tmpArr.push(tmpArr[tmpArr.length - 1]);
              var poly = turf.polygon([tmpArr]);
              if (turf.booleanPointInPolygon(pt, poly)) {
                callbackObj.staggeredEntities.push(entity);
              }
            }
            if (entity._polyline) {
              let { latitude, longitude } = GisTools.Cartesian3ToLngLat(callbackObj.car3Position);
              var pt = turf.point([longitude, latitude]);
              const polPositions = entity._polyline._positions._value;
              let tmpArr = [];
              for (let i = 0; i < polPositions.length; i++) {
                let res: any = GisTools.Cartesian3ToLngLat(polPositions[i]);
                tmpArr.push([res.longitude, res.latitude]);
              }
              var line = turf.lineString(tmpArr);
              if (turf.booleanPointOnLine(pt, line)) {
                callbackObj.staggeredEntities.push(entity);
              }
            }
          });
        }
      });
      if (callback) {
        callback(callbackObj);
      }
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  }

  getCartesian3FromPick(viewer: Cesium.Viewer, position: Cesium.Cartesian2) {
    let car3: any = null;
    let pick = viewer.scene.pick(position);
    if (viewer.scene.globe.depthTestAgainstTerrain) {
      if (Cesium.defined(pick)) {
        car3 = viewer.scene.pickPosition(position);
      } else {
        let ray:any = viewer.camera.getPickRay(position);
        car3 = viewer.scene.globe.pick(ray, viewer.scene);
      }
    } else {
      car3 = viewer.scene.camera.pickEllipsoid(position, viewer.scene.globe.ellipsoid);
    }
    return car3;
  }
}
export default new MounseEvent();
